package com.nlscan.qdkit.common.core.ext

import android.app.Activity
import android.os.Build
import android.view.View
import android.widget.Checkable
import androidx.fragment.app.Fragment
import com.nlscan.qdkit.common.core.R
import com.quvii.qvlib.util.ClickFilter
import com.quvii.qvlib.util.LogUtil

/**
 * 公共工具方法
 */

fun Int.retSuccess(): Boolean {
    return this == 0
}

fun logD(info: String?, tag: String? = generateTag(getCallerStackTraceElement())) {
    LogUtil.d(tag, info)
}

fun logI(info: String?, tag: String? = generateTag(getCallerStackTraceElement())) {
    LogUtil.i(tag, info)
}

fun logW(info: String?, tag: String? = generateTag(getCallerStackTraceElement())) {
    LogUtil.w(tag, info)
}

fun logE(info: String?, tag: String? = generateTag(getCallerStackTraceElement())) {
    LogUtil.e(tag, info)
}

fun logE(throwable: Throwable) {
    for (element in throwable.stackTrace) {
        logE("Error", element.toString())
    }
}

fun logTrace(info: String = "") {
    val stack = Thread.currentThread().stackTrace
    for (i in stack.indices) {
        if (i < 4) {
            continue
        }
        val fullClassName = stack[i].className
        val className = fullClassName.substring(fullClassName.lastIndexOf(".") + 1)
        logI(
            "Qv_trace $info",
            fullClassName + ":" + stack[i].methodName + "(" + className + ".java:" + stack[i].lineNumber + ")"
        )
    }
}

fun getCallerStackTraceElement(): StackTraceElement {
    return Thread.currentThread().stackTrace[4]
}

private fun generateTag(caller: StackTraceElement): String {
    var tag = "%s.%s(L:%d)"
    var callerClazzName = caller.className
    callerClazzName = callerClazzName.substring(callerClazzName.lastIndexOf(".") + 1)
    tag = String.format(tag, callerClazzName, caller.methodName, caller.lineNumber)
    return tag
}

fun Activity.setClickEvent(
    vararg views: View,
    needFilterClick: Boolean = true,
    listener: (view: View) -> Unit
) {
    for (view in views) {
        view.setOnClickListener {
            //过滤反复点击
            if (needFilterClick && ClickFilter.filter(it.id)) {
                return@setOnClickListener
            }

            listener(view)
        }
    }
}

fun Fragment.setClickEvent(
    vararg views: View,
    needFilterClick: Boolean = true,
    listener: (view: View) -> Unit
) {
    for (view in views) {
        view.setOnClickListener {
            //过滤反复点击
            if (needFilterClick && ClickFilter.filter(it.id)) {
                return@setOnClickListener
            }

            listener(view)
        }
    }
}

/**
 * 过滤重复点击的点击事件
 */
inline fun <T : View> T.singleClick(time: Long = 800L, crossinline block: (T) -> Unit) {
    setOnClickListener {
        val lastTime = getTag(R.id.common_record_time) as? Long ?: 0L
        val currentTime = System.currentTimeMillis()
        if (currentTime - lastTime > time || this is Checkable) {
            setTag(R.id.common_record_time, currentTime)
            block(this)
        } else {
            logD("click filter, time: ${time}, current: ${currentTime}, last: ${lastTime}, value: ${currentTime - lastTime}")
        }
    }
}

fun <T> ArrayList<T>.replace(callback: (old: T) -> T) {
    if (isEmpty()) {
        return
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        replaceAll {
            callback(it)
        }
    } else {
        val temp = ArrayList<T>(size)
        for (value in this) {
            temp.add(callback(value))
        }

        clear()
        addAll(temp)
    }
}

val logException = fun(e: Throwable) { logE(e) }